home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 1.iso / t_os / whisper / source / buff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-19  |  5.1 KB  |  264 lines

  1. /*********************************
  2.  
  3.     buffer I/O
  4.  
  5. **********************************/
  6. #include    <stdio.h>
  7. #include    <stdlib.h>
  8. #include    <string.h>
  9. #include    <ctype.h>
  10.  
  11. #define TRUE    1
  12. #define FALSE   0
  13. #define ERR     (-1)
  14.  
  15. #define unlink  remove
  16. #define    TMPFILE    "WHISTMP.$$$"
  17.  
  18. #define LIN_SIZ    82
  19. #define    BLK_SIZ        16384
  20. #define BUF_SIZ        181            /* 181 * 90 = 16290 */
  21. #define    BUF_LIN(n)    (n*BUF_SIZ)
  22. #define    LIN_BUF(n)    (n/BUF_SIZ)
  23. #define    LIN_MASK(n)    (n%BUF_SIZ)
  24. #define SEEK_POS(n)    ((long)(n)*BLK_SIZ)
  25.  
  26. typedef struct {
  27.     int        left;
  28.     int        right;
  29.     char    lin[LIN_SIZ];
  30. } LIN_PTR;
  31.  
  32. typedef struct _BP {
  33.     struct _BP  *next;
  34.     int         alno;
  35.     LIN_PTR    buf[BUF_SIZ];
  36. } BUF_PTR;
  37.  
  38. static FILE    *tfp=NULL;
  39. static int    free_no=ERR;
  40. static BUF_PTR    *top_buf=NULL;
  41. static int    tmp_drive_no=0;
  42. static char    tmp_file_name[80];
  43.  
  44. char    *macget(char *mac);
  45.  
  46. unsigned long int Freemem(void)
  47. {
  48.     int     mx;
  49.     unsigned long int sz,fm;
  50.     char    *dmy[128];
  51.  
  52.     for ( sz = 0x10000,fm = mx = 0 ; mx < 128 ; mx++ ) {
  53.     while ( (dmy[mx] = malloc(sz)) == NULL ) {
  54.         if ( (sz /= 2) < 0x1000 )
  55.         break;
  56.     }
  57.     if ( dmy[mx] == NULL )
  58.         break;
  59.     fm += sz;
  60.     }
  61.     while ( mx > 0 )
  62.     free(dmy[--mx]);
  63.     return fm;
  64. }
  65. int     BUF_init(char *drv)
  66. {
  67.     int     i;
  68.     BUF_PTR *bp;
  69.     unsigned long int l;
  70.     char    tmp[80];
  71.  
  72.     l = Freemem() / 3;
  73.     i = l / sizeof(BUF_PTR);
  74.     macvalset("FREEMEM",l);
  75.  
  76.     if ( (bp = (BUF_PTR *)malloc(sizeof(BUF_PTR)*i)) == NULL )
  77.     return ERR;
  78.  
  79.     top_buf = bp;
  80.     for ( i-- ; i > 0 ; i-- ) {
  81.         bp->next = bp + 1;
  82.         bp->alno = ERR;
  83.         bp++;
  84.     }
  85.     bp->next = NULL;
  86.     bp->alno = ERR;
  87.  
  88.     if ( drv == NULL ) {
  89.     getdir(tmp);
  90.     } else {
  91.     strcpy(tmp,drv);
  92.     strcat(tmp,"\\");
  93.     }
  94.     drv = tmp;
  95.     tmp_drive_no = toupper(drv[0]) - 'A';
  96.     sprintf(tmp_file_name,"%c:\\%s",tmp_drive_no+'A',TMPFILE);
  97.     macset("TMP",drv);
  98.  
  99.     return FALSE;
  100. }
  101. void    BUF_end(void)
  102. {
  103.     if ( tfp != NULL ) {
  104.     fclose(tfp);
  105.     unlink(tmp_file_name);
  106.     }
  107. }
  108. static void BUF_retry(no)
  109. int    no;
  110. {
  111.     static char *msg[]={
  112.     "Save Temp Seek Error        ",
  113.     "Save Temp Write Header Error",
  114.     "Save Temp Write Buffer Error",
  115.     "Load Temp Seek Error        ",
  116.     "Load Temp Read Header Error ",
  117.     "Save Temp Read Buffer Error ",
  118.     "New Temp File Can't open    ",
  119.     "New Temp Write Error        ",
  120.     "Temp File Can't open        "
  121.     };
  122.     int     i,rt=0;
  123.     FILE    *fp;
  124.     char    tmp[80];
  125.     char    buf[512];
  126.  
  127. RETRY:
  128.  
  129.     do {
  130.     macset("ERROR",msg[no]);
  131.     sprintf(tmp,"%c:",tmp_drive_no+'A');
  132.     macset("TMP",tmp);
  133.     MSG_wind("RETRY");
  134.     strcpy(buf,macget("DRIVE"));
  135.     tmp_drive_no = toupper(buf[0]) - 'A';
  136.     sprintf(tmp,"%c:\\%s",tmp_drive_no+'A',TMPFILE);
  137.     } while ( (fp = fopen(tmp,"w+b")) == NULL );
  138.  
  139.     if ( tfp != NULL ) {
  140.     fseek(tfp,0L,SEEK_SET);
  141.     while ( (i = fread(buf,1,512,tfp)) > 0 )
  142.         fwrite(buf,1,i,fp);
  143.     }
  144.  
  145.     if ( ferror(fp) ) {
  146.     fclose(fp);
  147.     unlink(tmp);
  148.     no = 7;
  149.     goto RETRY;
  150.     }
  151.  
  152.     if ( tfp != NULL ) {
  153.     fclose(tfp);
  154.     unlink(tmp_file_name);
  155.     }
  156.  
  157.     tfp = fp;
  158.     strcpy(tmp_file_name,tmp);
  159. }
  160. static void    BUF_save(bp)
  161. register BUF_PTR *bp;
  162. {
  163.     if ( tfp == NULL && (tfp = fopen(tmp_file_name,"w+b")) == NULL ) {
  164.     BUF_retry(8);
  165.     goto RETRY;
  166.     }
  167. RETRY:
  168.     if ( fseek(tfp,SEEK_POS(bp->alno),SEEK_SET) ) {
  169.     BUF_retry(0);
  170.     goto RETRY;
  171.     }
  172.     if ( fwrite((char *)bp,sizeof(BUF_PTR),1,tfp) < 1 ) {
  173.     BUF_retry(1);
  174.     goto RETRY;
  175.     }
  176. }
  177. static void BUF_load(no,bp)
  178. int     no;
  179. register BUF_PTR *bp;
  180. {
  181.     BUF_PTR *tp;
  182.  
  183.     if ( tfp == NULL && (tfp = fopen(tmp_file_name,"w+b")) == NULL ) {
  184.     BUF_retry(8);
  185.     goto RETRY;
  186.     }
  187. RETRY:
  188.     if ( fseek(tfp,SEEK_POS(no),SEEK_SET) ) {
  189.     BUF_retry(3);
  190.     goto RETRY;
  191.     }
  192.     tp = bp->next;
  193.     if ( fread((char *)bp,sizeof(BUF_PTR),1,tfp) < 1 ) {
  194.     bp->next = tp;
  195.     BUF_retry(4);
  196.     goto RETRY;
  197.     }
  198.     bp->next = tp;
  199. }
  200. static BUF_PTR *get_buf(register int no)
  201. {
  202.     register BUF_PTR *tp;
  203.     register BUF_PTR *bp;
  204.  
  205.     bp = top_buf;
  206.     while ( bp->alno != no ) {
  207.     if ( bp->next == NULL ) {
  208.             if ( bp->alno != ERR )
  209.                 BUF_save(bp);
  210.             if ( no != ERR )
  211.                 BUF_load(no,bp);
  212.             break;
  213.     }
  214.     tp = bp;
  215.     bp = bp->next;
  216.     }
  217.     if ( bp != top_buf ) {
  218.     tp->next = bp->next;
  219.     bp->next = top_buf;
  220.     top_buf = bp;
  221.     }
  222.     return bp;
  223. }
  224. LIN_PTR *get_lin(register int no)
  225. {
  226.     register BUF_PTR *bp;
  227.  
  228.     bp = get_buf(LIN_BUF(no));
  229.     return &(bp->buf[LIN_MASK(no)]);
  230. }
  231. int    xalloc(void)
  232. {
  233.     static int alno=0;
  234.  
  235.     int     i,n;
  236.     register LIN_PTR *lp;
  237.     register BUF_PTR *bp;
  238.  
  239.     if ( free_no == ERR ) {
  240.     bp = get_buf(ERR);
  241.     bp->alno = alno++;
  242.     n = BUF_LIN(bp->alno);
  243.     for ( i = 0 ; i < BUF_SIZ ; i++,n++ ) {
  244.         lp = &(bp->buf[i]);
  245.         lp->left = free_no;
  246.         free_no = n;
  247.     }
  248.     }
  249.     n = free_no;
  250.     lp = get_lin(free_no);
  251.     free_no = lp->left;
  252.     lp->left = lp->right = ERR;
  253.     lp->lin[0] = '\0';
  254.     return n;
  255. }
  256. int    xfree(int no)
  257. {
  258.     register LIN_PTR *lp;
  259.  
  260.     lp = get_lin(no);
  261.     lp->left = free_no;
  262.     free_no = no;
  263. }
  264.